/**
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package br.biofoco.p2p.services;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.PriorityBlockingQueue;

import com.google.inject.Inject;


public class ServiceExecutor implements Runnable {
	
	private final PriorityBlockingQueue<ServiceTask> queue = new PriorityBlockingQueue<ServiceTask>();

	private static final int THREAD_POOL = 4;
	private static final ExecutorCompletionService<ServiceResult<?>> executor = new ExecutorCompletionService<ServiceResult<?>>(Executors.newFixedThreadPool(THREAD_POOL));
	private ResultRepository repository;
	private final ServiceCatalogue catalogue;	
	private int submitted = 0;
	private ResultRetriever retriever = new ResultRetriever();

	
	@Inject
	public ServiceExecutor(ServiceCatalogue catalogue, ResultRepository repository){
		this.catalogue = catalogue;
		this.repository = repository;
	}
	
	public ServiceCatalogue getCatalogue(){
		return catalogue;
	}
	
	public void submit(ServiceTask task){
		queue.add(task);
		submitted++;
	}
	
	public void getResults() {
//		try {
//			BioResult<?> result = executor.take().get();
//			
//			System.out.println("RESULTADO: " + result);
//			
////			repository.add(result);
////			
////			System.out.println(repository.list());
//			
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (ExecutionException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
	public void run() {
		while (true){
			try {
				ServiceTask task = queue.take();
				executor.submit(task); // submit service
			
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}	
	
	public void start() {
		Thread t = new Thread(this);
		t.start();
		retriever.start();
	}
	
	private class ResultRetriever implements Runnable {

		public void run() {
			try {
				while (true) {
					Future<ServiceResult<?>> future = executor.take();
					ServiceResult<?> result = future.get();
					repository.add(result);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
		}
		
		public void start() {
			Thread t = new Thread(this);
			t.start();
		}
		
	}
}
